1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.SortedSet;
29 import java.util.TreeSet;
30
31 import javax.annotation.Nullable;
32
33
34
35
36
37
38 public abstract class ImmutableSortedSet<E>
39 extends ForwardingImmutableSet<E> implements SortedSet<E>, SortedIterable<E> {
40
41
42
43
44
45
46
47
48 @Deprecated public static <E> ImmutableSortedSet.Builder<E> builder() {
49 throw new UnsupportedOperationException();
50 }
51
52
53 @SuppressWarnings("unchecked")
54 private static final Comparator NATURAL_ORDER = Ordering.natural();
55
56 @SuppressWarnings("unchecked")
57 private static final ImmutableSortedSet<Object> NATURAL_EMPTY_SET =
58 new EmptyImmutableSortedSet<Object>(NATURAL_ORDER);
59
60 @SuppressWarnings("unchecked")
61 private static <E> ImmutableSortedSet<E> emptySet() {
62 return (ImmutableSortedSet<E>) NATURAL_EMPTY_SET;
63 }
64
65 static <E> ImmutableSortedSet<E> emptySet(
66 Comparator<? super E> comparator) {
67 checkNotNull(comparator);
68 if (NATURAL_ORDER.equals(comparator)) {
69 return emptySet();
70 } else {
71 return new EmptyImmutableSortedSet<E>(comparator);
72 }
73 }
74
75 public static <E> ImmutableSortedSet<E> of() {
76 return emptySet();
77 }
78
79 public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
80 E element) {
81 return ofInternal(Ordering.natural(), element);
82 }
83
84 @SuppressWarnings("unchecked")
85 public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
86 E e1, E e2) {
87 return ofInternal(Ordering.natural(), e1, e2);
88 }
89
90 @SuppressWarnings("unchecked")
91 public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
92 E e1, E e2, E e3) {
93 return ofInternal(Ordering.natural(), e1, e2, e3);
94 }
95
96 @SuppressWarnings("unchecked")
97 public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
98 E e1, E e2, E e3, E e4) {
99 return ofInternal(Ordering.natural(), e1, e2, e3, e4);
100 }
101
102 @SuppressWarnings("unchecked")
103 public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
104 E e1, E e2, E e3, E e4, E e5) {
105 return ofInternal(Ordering.natural(), e1, e2, e3, e4, e5);
106 }
107
108 @SuppressWarnings("unchecked")
109 public static <E extends Comparable<? super E>> ImmutableSortedSet<E> of(
110 E e1, E e2, E e3, E e4, E e5, E e6, E... remaining) {
111 int size = remaining.length + 6;
112 List<E> all = new ArrayList<E>(size);
113 Collections.addAll(all, e1, e2, e3, e4, e5, e6);
114 Collections.addAll(all, remaining);
115
116 return ofInternal(Ordering.natural(), (E[]) all.toArray(new Comparable[0]));
117 }
118
119 private static <E> ImmutableSortedSet<E> ofInternal(
120 Comparator<? super E> comparator, E... elements) {
121 checkNotNull(elements);
122 switch (elements.length) {
123 case 0:
124 return emptySet(comparator);
125 default:
126 SortedSet<E> delegate = new TreeSet<E>(comparator);
127 for (E element : elements) {
128 checkNotNull(element);
129 delegate.add(element);
130 }
131 return new RegularImmutableSortedSet<E>(delegate, false);
132 }
133 }
134
135 public static <E> ImmutableSortedSet<E> copyOf(Collection<? extends E> elements) {
136 return copyOfInternal((Ordering<E>) Ordering.natural(), (Collection) elements, false);
137 }
138
139 public static <E> ImmutableSortedSet<E> copyOf(Iterable<? extends E> elements) {
140 return copyOfInternal((Ordering<E>) Ordering.natural(), (Iterable) elements, false);
141 }
142
143 public static <E> ImmutableSortedSet<E> copyOf(Iterator<? extends E> elements) {
144 return copyOfInternal((Ordering<E>) Ordering.natural(), (Iterator) elements);
145 }
146
147 public static <E extends Comparable<? super E>> ImmutableSortedSet<E> copyOf(
148 E[] elements) {
149 return ofInternal(Ordering.natural(), elements);
150 }
151
152 public static <E> ImmutableSortedSet<E> copyOf(
153 Comparator<? super E> comparator, Iterable<? extends E> elements) {
154 checkNotNull(comparator);
155 return copyOfInternal(comparator, elements, false);
156 }
157
158 public static <E> ImmutableSortedSet<E> copyOf(
159 Comparator<? super E> comparator, Collection<? extends E> elements) {
160 checkNotNull(comparator);
161 return copyOfInternal(comparator, elements, false);
162 }
163
164 public static <E> ImmutableSortedSet<E> copyOf(
165 Comparator<? super E> comparator, Iterator<? extends E> elements) {
166 checkNotNull(comparator);
167 return copyOfInternal(comparator, elements);
168 }
169
170 @SuppressWarnings("unchecked")
171 public static <E> ImmutableSortedSet<E> copyOfSorted(SortedSet<E> sortedSet) {
172 Comparator<? super E> comparator = sortedSet.comparator();
173 if (comparator == null) {
174 comparator = NATURAL_ORDER;
175 }
176 return copyOfInternal(comparator, sortedSet.iterator());
177 }
178
179 private static <E> ImmutableSortedSet<E> copyOfInternal(
180 Comparator<? super E> comparator, Iterable<? extends E> elements,
181 boolean fromSortedSet) {
182 checkNotNull(comparator);
183
184 boolean hasSameComparator
185 = fromSortedSet || hasSameComparator(elements, comparator);
186 if (hasSameComparator && (elements instanceof ImmutableSortedSet)) {
187 @SuppressWarnings("unchecked")
188 ImmutableSortedSet<E> result = (ImmutableSortedSet<E>) elements;
189 boolean isSubset = (result instanceof RegularImmutableSortedSet)
190 && ((RegularImmutableSortedSet) result).isSubset;
191 if (!isSubset) {
192
193
194 return result;
195 }
196 }
197 return copyOfInternal(comparator, elements.iterator());
198 }
199
200 private static <E> ImmutableSortedSet<E> copyOfInternal(
201 Comparator<? super E> comparator, Iterator<? extends E> elements) {
202 checkNotNull(comparator);
203 if (!elements.hasNext()) {
204 return emptySet(comparator);
205 }
206 SortedSet<E> delegate = new TreeSet<E>(comparator);
207 while (elements.hasNext()) {
208 E element = elements.next();
209 checkNotNull(element);
210 delegate.add(element);
211 }
212 return new RegularImmutableSortedSet<E>(delegate, false);
213 }
214
215 private static boolean hasSameComparator(
216 Iterable<?> elements, Comparator<?> comparator) {
217 if (elements instanceof SortedSet) {
218 SortedSet<?> sortedSet = (SortedSet<?>) elements;
219 Comparator<?> comparator2 = sortedSet.comparator();
220 return (comparator2 == null)
221 ? comparator == Ordering.natural()
222 : comparator.equals(comparator2);
223 }
224 return false;
225 }
226
227
228 static <E> ImmutableSortedSet<E> unsafeDelegateSortedSet(
229 SortedSet<E> delegate, boolean isSubset) {
230 return delegate.isEmpty()
231 ? emptySet(delegate.comparator())
232 : new RegularImmutableSortedSet<E>(delegate, isSubset);
233 }
234
235
236
237 private Comparator<E> unusedComparatorForSerialization;
238 private E unusedElementForSerialization;
239
240 private transient final SortedSet<E> sortedDelegate;
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255 ImmutableSortedSet(Comparator<? super E> comparator) {
256 this(Sets.newTreeSet(comparator));
257 }
258
259 ImmutableSortedSet(SortedSet<E> sortedDelegate) {
260 super(sortedDelegate);
261 this.sortedDelegate = Collections.unmodifiableSortedSet(sortedDelegate);
262 }
263
264 public Comparator<? super E> comparator() {
265 return sortedDelegate.comparator();
266 }
267
268 @Override
269 public UnmodifiableIterator<E> iterator() {
270 return super.iterator();
271 }
272
273 @Override
274 public Object[] toArray() {
275 return ObjectArrays.toArrayImpl(this);
276 }
277
278 @Override
279 public <T> T[] toArray(T[] other) {
280 return ObjectArrays.toArrayImpl(this, other);
281 }
282
283 @Override public boolean contains(@Nullable Object object) {
284 try {
285
286
287 return object != null && sortedDelegate.contains(object);
288 } catch (ClassCastException e) {
289 return false;
290 }
291 }
292
293 @Override public boolean containsAll(Collection<?> targets) {
294 for (Object target : targets) {
295 if (target == null) {
296
297
298 return false;
299 }
300 }
301 try {
302 return sortedDelegate.containsAll(targets);
303 } catch (ClassCastException e) {
304 return false;
305 }
306 }
307
308 public E first() {
309 return sortedDelegate.first();
310 }
311
312 public ImmutableSortedSet<E> headSet(E toElement) {
313 checkNotNull(toElement);
314 try {
315 return unsafeDelegateSortedSet(sortedDelegate.headSet(toElement), true);
316 } catch (IllegalArgumentException e) {
317 return emptySet(comparator());
318 }
319 }
320
321 E higher(E e) {
322 checkNotNull(e);
323 Iterator<E> iterator = tailSet(e).iterator();
324 while (iterator.hasNext()) {
325 E higher = iterator.next();
326 if (comparator().compare(e, higher) < 0) {
327 return higher;
328 }
329 }
330 return null;
331 }
332
333 ImmutableSortedSet<E> headSet(E toElement, boolean inclusive) {
334 checkNotNull(toElement);
335 if (inclusive) {
336 E tmp = higher(toElement);
337 if (tmp == null) {
338 return this;
339 }
340 toElement = tmp;
341 }
342 return headSet(toElement);
343 }
344
345 public E last() {
346 return sortedDelegate.last();
347 }
348
349 public ImmutableSortedSet<E> subSet(E fromElement, E toElement) {
350 return subSet(fromElement, true, toElement, false);
351 }
352
353 ImmutableSortedSet<E> subSet(E fromElement, boolean fromInclusive, E toElement,
354 boolean toInclusive) {
355 checkNotNull(fromElement);
356 checkNotNull(toElement);
357 int cmp = comparator().compare(fromElement, toElement);
358 checkArgument(cmp <= 0, "fromElement (%s) is less than toElement (%s)", fromElement, toElement);
359 if (cmp == 0 && !(fromInclusive && toInclusive)) {
360 return emptySet(comparator());
361 }
362 return tailSet(fromElement, fromInclusive).headSet(toElement, toInclusive);
363 }
364
365 public ImmutableSortedSet<E> tailSet(E fromElement) {
366 checkNotNull(fromElement);
367 try {
368 return unsafeDelegateSortedSet(sortedDelegate.tailSet(fromElement), true);
369 } catch (IllegalArgumentException e) {
370 return emptySet(comparator());
371 }
372 }
373
374 ImmutableSortedSet<E> tailSet(E fromElement, boolean inclusive) {
375 checkNotNull(fromElement);
376 if (!inclusive) {
377 E tmp = higher(fromElement);
378 if (tmp == null) {
379 return emptySet(comparator());
380 }
381 fromElement = tmp;
382 }
383 return tailSet(fromElement);
384 }
385
386 public static <E> Builder<E> orderedBy(Comparator<E> comparator) {
387 return new Builder<E>(comparator);
388 }
389
390 public static <E extends Comparable<?>> Builder<E> reverseOrder() {
391 return new Builder<E>(Ordering.natural().reverse());
392 }
393
394 public static <E extends Comparable<?>> Builder<E> naturalOrder() {
395 return new Builder<E>(Ordering.natural());
396 }
397
398 public static final class Builder<E> extends ImmutableSet.Builder<E> {
399 private final Comparator<? super E> comparator;
400
401 public Builder(Comparator<? super E> comparator) {
402 this.comparator = checkNotNull(comparator);
403 }
404
405 @Override public Builder<E> add(E element) {
406 super.add(element);
407 return this;
408 }
409
410 @Override public Builder<E> add(E... elements) {
411 super.add(elements);
412 return this;
413 }
414
415 @Override public Builder<E> addAll(Iterable<? extends E> elements) {
416 super.addAll(elements);
417 return this;
418 }
419
420 @Override public Builder<E> addAll(Iterator<? extends E> elements) {
421 super.addAll(elements);
422 return this;
423 }
424
425 @Override public ImmutableSortedSet<E> build() {
426 return copyOfInternal(comparator, contents.iterator());
427 }
428 }
429 }